#include "stdafx.h"
#include <stdio.h>
#include "F:\Pratice\vc98\myntlib\myntlib.h"
#include <malloc.h>
#ifdef NDEBUG
#pragma comment(lib,"F:/Pratice/vc98/myntlib/Release/myntlib.lib")
#else
#pragma comment(lib,"F:/Pratice/vc98/myntlib/Debug/myntlib.lib")
#endif

#include "rdb.h"
int open_rdb(wchar_t* name, wchar_t* file,RDB* rdb){
    HKEY key;
    if(wcslen(name) > 63) return 0;
    LONG ret = RegOpenKeyW(HKEY_LOCAL_MACHINE,name,&key);
    if (ret != ERROR_SUCCESS) {
        priv_access(L"SeRestorePrivilege",SE_PRIVILEGE_ENABLED,0);
        ret = RegLoadKeyW(HKEY_LOCAL_MACHINE,name,file);
        priv_access(L"SeRestorePrivilege",0,0);
        if (ret != ERROR_SUCCESS)
            return 0;
        ret = RegOpenKeyW(HKEY_LOCAL_MACHINE,name,&key);
        if (ret != ERROR_SUCCESS)
            return 0;
    }
    wcscpy(rdb->name,name);
    rdb->key = key;
    return 1;
}
void close_rdb(RDB* rdb) {
    LONG ret = RegCloseKey(rdb->key);
    priv_access(L"SeRestorePrivilege",SE_PRIVILEGE_ENABLED,0);
    ret = RegUnLoadKeyW(HKEY_LOCAL_MACHINE,rdb->name);
    priv_access(L"SeRestorePrivilege",0,0);
}
int rdb_put(RDB* rdb,wchar_t* name,wchar_t* value) {
    LONG ret = 0;
    DWORD type;
    int tlen = wcslen(value)*sizeof(wchar_t) + 2;
    DWORD bsize = 256 + tlen;
    WCHAR* buf = (WCHAR*)_alloca(bsize);
    DWORD size = 256;
    ret = RegQueryValueExW(rdb->key,name,0,&type,(PBYTE)buf,&size);
    if ( ret == ERROR_FILE_NOT_FOUND) {
        ret = RegSetValueExW(rdb->key,name,0,REG_MULTI_SZ,(LPBYTE )value,tlen);
        return 1;
    }
    else if ( ret == ERROR_MORE_DATA) {
        bsize = size + tlen;
        buf = (WCHAR*)_alloca(bsize);
        ret = RegQueryValueExW(rdb->key,name,0,&type,(PBYTE)buf,&size);
        if (ret != ERROR_SUCCESS)
            return 0;
        
    }
    else if (ret == ERROR_SUCCESS) {
        if (size < 5){
            ret = RegSetValueExW(rdb->key,name,0,REG_MULTI_SZ,(LPBYTE )value,tlen);
            return 1;
        }
    }
    else {
        return 0;
    }
    WCHAR* start = buf;
    WCHAR* end = &buf[size/2];
    while (1) {
        if (wcscmp(buf,value) == 0)
            return 1;
        buf = &buf[wcslen(buf)+1];
        if (buf >= end || buf [0] == 0)
            break;
    }
    size = (&buf[0] - start) * 2;
    wcscpy(buf,value);
    ret = RegSetValueExW(rdb->key,name,0,REG_MULTI_SZ,(LPBYTE )start,size+tlen);
    return 1;
}
int rdb_get(RDB* rdb,wchar_t* name,wchar_t** value) {
    return 1;
}
void testdb(){
    RDB rdb;
    open_rdb(L"ipnames",L"d:/ipnames",&rdb);
    for(int i = 0;i< 10;i++) {
        WCHAR tmp[32];
        WCHAR tmp2[32]= {0};
        _ultow(i,tmp,10);
        _ultow(i+0xfffff,tmp2,10);
        rdb_put(&rdb,tmp,tmp2);
    }
    //close_rdb(&rdb);
}